﻿#pragma once
#include <QJsonObject>
#include <QJsonArray>
#include <QJsonDocument>

#include <QVariant>
#include <QVariantList>
#include <QVariantMap>

/**
* then you can use it.
*
* 1. init AppInfo from Json by construct or operator=
*

*
*   QJsonObject obj;
*   AppInfo info = obj;
*
* 2. convert object to Json or VariantMap by operator
*
*
*   AppInfo info;
* ...
*   QJsonObject obj = info;
*   QVariant var = info;
*   QVariantMap map = info;
*
**/

///@brief 序列化(将C++对象的值赋予给json)
/// QVariant 映射成普通对象
/// QJsonObject映射成json对象
/// QVariantMap 返回map
#define JsonSerialize_Begin()    \
    public:                                                         \
    operator QVariant() const{                  \
    return QVariant::fromValue( this->operator  QVariantMap() );                                               \
    };                                                                      \
    \
    operator QJsonObject() const{                   \
    return  QJsonObject::fromVariantMap(this->operator  QVariantMap());                                                                       \
    }                                                                       \
    \
    operator QVariantMap() const{                                   \
    QVariantMap m_VarMap;


#define JsonSerialize_End()                                                                                       \
    return   m_VarMap ;                                       \
    }

///将其他map映射到此map
#define JsonPureProperty(Name)  m_VarMap.unite((QVariantMap)m_##Name);

///将对象映射到map中
#define JsonProperty(Name)               \
{                                                                        \
    m_VarMap[#Name]  = QVariant::fromValue(m_##Name);                              \
    if(m_VarMap.value(#Name).isNull()){            \
    m_VarMap.remove(#Name);                                                                 \
    }                                       \
    }

///将List映射到map中
#define JsonContianerProperty(Name) \
{ \
    QVariantList list;                                          \
    lst.reserve(m_##Name.size());                   \
    for(const auto &t : m_##Name){                                                       \
    list<<QVariant::fromValue(t);                 \
    }                                                               \
    }

///反序列化 将读取出来的json转成对象
/// 通过构造函数
#define JsonDeserialize_Begin(class_name)            \
    public:                                                                     \
    class_name(const QJsonObject & other)        \
    {                                                                              \
    QVariantMap vmap = other.toVariantMap();

#define JsonDeserialize_End()  }

///通过重载运算符
#define JsonPartialDeserialize_Begin(class_name) \
    public:\
    class_name &operator=(const QJsonObject & other){    \
    QVariantMap vmap = other.fromVariantMap(); \
    }

#define JsonPartialDeserialize_End()    \
    return *this; \
    }
//反序列对象转换
#define JsonDeserializeProperty(Name)  m_##Name = vmap.value(#Name).value<decltype(m_##Name)>();
//反序列化列表转换
#define JsonDeserializeContainerProperty(Name)\
    if(vmap.value(#Name).canConvert<QVariantList>()){\
    const auto & list = vmap.value(m_##Name).value<QVariantList>() ;                                                  \
    m_##Name.clear(); \
    m_##Name.reserve(list.size());\
    for (const auto &v : list) {                                                               \
    m_##NAME.push_back(v.value<decltype(m_##NAME)::value_type>());                         \
    } \
    }\

